package alipay

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/pkg/errors"
	"github.com/smartwalle/alipay/v3"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"time"
	"unsafe"
)

type Close struct {
	OutTradeNo string `json:"outTradeNo"`
}

// 退款
func (close Close) NativeCloseOrder() (bool, error) {
	var p = alipay.TradeClose{}
	p.OutTradeNo = close.OutTradeNo
	_, err := MyClient.AlipayClient.TradeClose(p)
	if err != nil {
		return false, err
	} else {
		return true, nil
	}
}

type CallbackContent struct {
	Attach        string    `json:"attach"`
	OutTradeNo    string    `json:"out_trade_no"`
	TransactionId string    `json:"transaction_id"`
	TradeType     string    `json:"trade_type"`
	TradeState    string    `json:"trade_state"`
	SuccessTime   time.Time `json:"success_time"`
	Payer         struct {
		Openid string `json:"openid"`
	}
	Amount struct {
		Total    int64  `json:"total"`
		Currency string `json:"currency"`
	}
}

func Callback(request *http.Request) (bool, error) {
	request.ParseForm()
	if err := MyClient.AlipayClient.VerifySign(request.Form); err != nil {
		log.Println("回调验证签名发生错误", err)
		//writer.WriteHeader(http.StatusBadRequest)
		//writer.Write([]byte("回调验证签名发生错误"))
		return false, errors.New("回调验证签名发生错误")
	}
	log.Println("回调验证签名通过")
	// 示例一：使用已有接口进行查询
	var outTradeNo = request.Form.Get("out_trade_no")
	b, _ := json.Marshal(request.Form)
	fmt.Println("支付回调数据", string(b))
	var p = alipay.TradeQuery{}
	p.OutTradeNo = outTradeNo
	rsp, err := MyClient.AlipayClient.TradeQuery(p)
	if err != nil {
		//writer.WriteHeader(http.StatusBadRequest)
		//writer.Write([]byte(fmt.Sprintf("验证订单 %s 信息发生错误: %s", outTradeNo, err.Error())))
		return false, errors.New(fmt.Sprintf("验证订单 %s 信息发生错误: %s", outTradeNo, err.Error()))
	}

	if rsp.IsFailure() {
		//writer.WriteHeader(http.StatusBadRequest)
		//writer.Write([]byte(fmt.Sprintf("验证订单 %s 信息发生错误: %s-%s", outTradeNo, rsp.Msg, rsp.SubMsg)))
		return false, errors.New(fmt.Sprintf("验证订单 %s 信息发生错误: %s-%s", outTradeNo, rsp.Msg, rsp.SubMsg))
	}
	log.Println(fmt.Sprintf("订单 %s 支付成功", outTradeNo))

	decodedString, err := url.QueryUnescape(request.Form.Get("passback_params"))
	if err != nil {
		return false, errors.New("url错误")
	}

	callbackContent := CallbackContent{
		OutTradeNo: request.Form.Get("out_trade_no"),
		TradeType:  request.Form.Get("trade_status_sync"),
		TradeState: request.Form.Get("trade_status"),
	}
	callbackContentByte, _ := json.Marshal(callbackContent)

	reader := bytes.NewReader(callbackContentByte)
	request1, err := http.NewRequest("POST", decodedString, reader)
	request1.Header.Set("Content-Type", "application/json;charset=UTF-8")
	client := http.Client{}
	resp, err := client.Do(request1)
	if err != nil {
		fmt.Println(err.Error())
		return true, err
	}

	respBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err.Error())
		return true, err
	}
	//byte数组直接转成string，优化内存
	str := (*string)(unsafe.Pointer(&respBytes))
	fmt.Println(*str)

	if err != nil {
		fmt.Println(err)
		return false, err
	}

	return true, nil
	//writer.WriteHeader(http.StatusOK)
	//writer.Write([]byte(fmt.Sprintf("订单 %s 支付成功", outTradeNo)))
}
